import 'dart:developer';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';

import '../lib_baseview/utils/cache_util.dart';
import 'header_interceptor.dart';
import 'http_response.dart';
import 'old/url_config.dart';

typedef LCResponseHandler = void Function(bool success, dynamic response);

class HttpHelper {
  factory HttpHelper.instance() => _instance;

  static final HttpHelper _instance = HttpHelper._internal();

  late Dio dio;

  HttpHelper._internal() {
    _init();
  }

  _init() {
    dio = Dio(
      BaseOptions(
        baseUrl: UrlConfig.apiDomain,
        connectTimeout: const Duration(seconds: 120),
        receiveTimeout: const Duration(seconds: 120),
        sendTimeout: const Duration(seconds: 120),
      ),
    );
    updateProxy();

    dio.interceptors.add(HeaderInterceptor());

    if (kDebugMode) {
      //设置logPrint，解决日志长度过长无法打印bug
      dio.interceptors.add(
        LogInterceptor(
          requestBody: true,
          responseBody: true,
          logPrint: (Object? object) {
            log("$object");
          },
        ),
      );
    }
  }

  void updateProxy() {
    // if (!GlobalConfig.isDebug) return;
    var ip = CacheUtil.get('ip');
    var port = CacheUtil.get('port');
    // var pb = CacheUtil.getBool('pb', true);

    if (ip.isEmpty || port.isEmpty) return;

    // if (pb) {
    //   dio.options.headers[Headers.acceptHeader] = headerProto;
    // } else {
    //   dio.options.headers[Headers.acceptHeader] = Headers.jsonContentType;
    // }

    // if (_useHttp2) {
    //   dio.httpClientAdapter.close();
    //   dio.httpClientAdapter = Http2Adapter(connectionManager);
    //   http1RetryInterceptor.updateProxy(ip, port);
    // } else {

    dio.httpClientAdapter = IOHttpClientAdapter(
      createHttpClient: () {
        final client = HttpClient();
        client.findProxy = (uri) {
          return (ip.isEmpty || port.isEmpty) ? 'DIRECT' : 'PROXY $ip:$port';
        };
        return client;
      },
    );
  }

  Future<HttpResponse> get(
    String path, {
    Map<String, dynamic>? params,
    bool showLoading = false,
    bool showToast = true,
  }) async {
    try {
      if (showLoading && isLoading == false) {
        isLoading = true;

        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }
      Response response = await dio.get(path, queryParameters: params);
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }

      return _dealResponse(response, path, showToast: showToast, argument: params);
    } catch (e) {
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(null, path, showToast: showToast, argument: params);
    }
  }

  bool isLoading = false;

  Future<HttpResponse> post(
    String path, {
    Map<String, dynamic>? body,
    Map<String, dynamic>? headers,
    bool showLoading = false,
    bool showToast = true,
  }) async {
    try {
      if (showLoading && isLoading == false) {
        isLoading = true;
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }

      // FormData formData = FormData.fromMap(body ?? {});
      // Response response = await dio.post(path, data: body);

      if (kDebugMode) {
        print("body::$body ");
      }

      FormData formData = FormData.fromMap(body ?? {});
      // 使用 Options 添加请求头
      Options options = Options(headers: headers);

      Response response = await dio.post(path, data: formData, options: options);

      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(response, path, showToast: showToast, argument: body);
    } catch (e) {
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }

      Response? response;
      if (e is DioException) {
        response = e.response;
      }
      return _dealResponse(response, path, showToast: showToast, argument: body);
    }
  }

  Future<HttpResponse> put(
    String path, {
    Map<String, dynamic>? body,
    bool showLoading = false,
    bool showToast = false,
  }) async {
    try {
      if (showLoading && isLoading == false) {
        isLoading = true;
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }
      FormData formData = FormData.fromMap(body ?? {});
      Response response = await dio.put(path, data: formData);
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(response, path, showToast: showToast, argument: body);
    } catch (e) {
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(null, path, showToast: showToast, argument: body);
    }
  }

  Future<HttpResponse> delete(
    String path, {
    Map<String, dynamic>? body,
    bool showLoading = false,
    bool showToast = true,
  }) async {
    try {
      if (showLoading && isLoading == false) {
        isLoading = true;
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }
      FormData formData = FormData.fromMap(body ?? {});
      Response response = await dio.delete(path, data: formData);
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(response, path, showToast: showToast, argument: body);
    } catch (e) {
      if (showLoading && isLoading) {
        isLoading = false;
        EasyLoading.dismiss();
      }
      return _dealResponse(null, path, showToast: showToast, argument: body);
    }
  }

  Future<HttpResponse> patch(
    String path, {
    Map<String, dynamic>? body,
    bool showLoading = false,
    bool showToast = true,
  }) async {
    try {
      if (showLoading) {
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }
      FormData formData = FormData.fromMap(body ?? {});
      Response response = await dio.patch(path, data: formData);
      return _dealResponse(response, path, showToast: showToast, argument: body);
    } catch (e) {
      return _dealResponse(null, path, showToast: showToast, argument: body);
    }
  }

  /// 返回结果为空代表请求异常
  HttpResponse _dealResponse(Response? response, String? path,
      {bool showToast = true, Map<String, dynamic>? argument}) {
    if (response?.statusCode == 200) {
      // XLogTrack.instance.logger.log(
      //   Logger.level,
      //   "path:$path body:$argument response:$response",
      // );

      final body = response!.data;

      if (body["status"] == 500) {
        return HttpResponse(isSuccess: false, result: body);
      }

      // final error = body["error"];
      // if (body["code"] == 401) {
      //   // EventBusTool.fire(FHUserHasPostCardSucceedEvent());
      //   // UserCenter().logout();
      // }

      // if (error != null) {
      //   switch (body["code"]) {
      //     case 401:
      //       // token过期，跳转到登陆页

      //       break;
      //     case 12001:
      //       // "纸条重复回复".toast();
      //       break;
      //     case 12002:
      //       // "纸条推荐次数不够".toast();
      //       break;
      //     case 12003:
      //       // "纸条回复次数不够".toast();
      //       break;
      //   }
      //   if (body["code"] == 10006 || body["code"] == 10007) {
      //     ///10006账号封禁-  10007多设备登录
      //     // EventBusTool.fire(FHUserHasPostCardSucceedEvent());
      //     // UserCenter().logout();
      //   }

      //   if (showToast) {
      //     // "$error".toast();
      //   }
      //   return HttpResponse(isSuccess: false, result: error);
      // }
      // if (body["code"] != 200) {
      //   /// 进入深度聊天提醒
      //   if (body["code"] == 14001 ||
      //       body["code"] == 14002 ||
      //       body["code"] == 14003 ||
      //       body["code"] == 16001 ||
      //       body["code"] == 14004) {
      //     /// 这里是不需要 弹出 showToast
      //     showToast = false;
      //   }
      //   if (showToast) {
      //     // "${body["message"]}".toast();
      //   }
      //   return HttpResponse(isSuccess: false, result: body);
      // }

      return HttpResponse(isSuccess: true, result: body["data"]);
    } else {
      // XLogTrack.instance.logger.log(
      //   Logger.level,
      //   "path:$path body:$argument response:$response",
      // );

      // "Oops! Something went wrong with the network. Please check and retry!"
      //     .toast();
      return HttpResponse(
        isSuccess: false,
        result: {
          "status": -1,
          "description": "Oops! Something went wrong with the network. Please check and retry!",
        },
      );
    }
  }

  Future<dynamic> simpleGet(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    bool showLoading = false,
  }) async {
    try {
      if (showLoading) {
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }

      if (headers != null && headers.isNotEmpty) {
        dio.options.headers.addAll(headers);
      }
      Response response = await dio.get(path, queryParameters: params);
      return response.data;
    } catch (e) {
      return null;
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<bool> download(String path, dynamic savePath,
      {ProgressCallback? onReceiveProgress, bool showLoading = false}) async {
    try {
      if (showLoading) {
        EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      }
      var response = await dio.download(path, savePath, onReceiveProgress: onReceiveProgress);
      return response.statusCode == 200;
    } catch (e) {
      return false;
    } finally {
      EasyLoading.dismiss();
    }
  }

  /// 获取图片字节码数据
  Future<Uint8List> getImageBytes(String url) async {
    return (await NetworkAssetBundle(Uri.parse(url)).load(url)).buffer.asUint8List();
  }

  /// 多文件上传函数
  /// uploadProgressBlock：上传进度回调
  /// completionHandler：上传完成
  Future<HttpResponse?> multiUpload(
    String api,
    Map<String, dynamic> parameters,
    List<AssetEntity> dataArr, {
    void Function(double progress)? uploadProgressBlock,
    LCResponseHandler? completionHandler,
  }) async {
    try {
      EasyLoading.show(maskType: EasyLoadingMaskType.clear, dismissOnTap: false);

      // 创建 FormData
      FormData formData = FormData();
      // 添加请求参数
      parameters.forEach((key, value) {
        formData.fields.add(MapEntry(key, value.toString()));
      });

      // 添加文件
      for (var i = 0; i < dataArr.length; i++) {
        AssetEntity file = dataArr[i];
        String? fileExtension = parameters['name'];

        final tmpfiel = await file.file;

        if (tmpfiel?.path != null) {
          formData.files.add(MapEntry(
            'file',
            await MultipartFile.fromFile(
              /// 注意：这里的tmpfiel?.path为空的话就没有意义了
              tmpfiel?.path ?? '',
              filename: fileExtension,
              // contentType: Headers.contentTypeHeader,
            ),
          ));
        } else {
          print('文件路径为空');
        }
      }

      /// 为了严谨 这里可以判断  formData 是否为空，为空直接返回

      print('');

      // 发送 POST 请求并监听上传进度
      Response response = await dio.post(
        api,
        data: formData,
        onSendProgress: (int sent, int total) {
          if (uploadProgressBlock != null) {
            double progress = sent / total;
            uploadProgressBlock(progress);
          }
        },
      );
      EasyLoading.dismiss();
      return _dealResponse(response, api, showToast: true, argument: parameters);
      // 处理响应
      if (response.statusCode == 200) {
        // completionHandler(true, response.data);

        completionHandler?.call(true, response.data);
      } else {
        // completionHandler(false, response.statusCode);
        completionHandler?.call(false, response.statusCode);
      }

//  Response response = await dio.post(path, data: formData);
    } catch (e) {
      // 处理错误
      EasyLoading.dismiss();
      // completionHandler(false, e.toString());
      completionHandler?.call(false, e.toString());
    }
  }

  ///上传单个文件
  Future<HttpResponse> uploadFile(File file, String type) async {
    try {
      EasyLoading.show(maskType: EasyLoadingMaskType.clear);
      // 创建 FormData 对象
      FormData formData = FormData();
      print(file!.path!);
      print(file.path.split('/').last);
// 添加文件
      formData.files.add(MapEntry(
        "file", // 字段名（需与服务器一致）
        await MultipartFile.fromFile(
          file!.path!,
          filename: file.path.split('/').last,
        ),
      ));
      Map<String, dynamic> parameters = {
        "file": file.path,
        "type": type,
        "size": file.lengthSync(),
        "name": file.path.split('/').last,
      };
      // 发送请求
      Response response = await dio.post(
        "/api/v1/global/upload",
        data: formData,
        queryParameters: parameters,
        options: Options(responseType: ResponseType.json),
      );

      EasyLoading.dismiss();
      return _dealResponse(response, "/api/v1/global/upload", showToast: true, argument: parameters);
    } catch (e) {
      EasyLoading.dismiss();
      return HttpResponse(
        isSuccess: false,
        result: {
          "status": e.hashCode,
          "description": e.toString(),
        },
      );
    }
  }
}
